import {
  TextureLoader,
  Color,
  Path,
  AmbientLight,
  DirectionalLight,
  PointLight,
  Group,
  RepeatWrapping,
  Vector3,
  PerspectiveCamera,
  OrthographicCamera,
  Box3,
  MeshStandardMaterial,
  MeshMatcapMaterial,
  MeshLambertMaterial,
  MeshBasicMaterial,
  MeshToonMaterial,
  MeshPhongMaterial,
  MeshPhysicalMaterial,
  Mesh,
  PCFSoftShadowMap,
  WebGLRenderer,
  Cache,
  PlaneGeometry,
  Fog,
  Scene
} from 'three';

import CameraSystem from './camera-system.js';


const builtinTextures = {
  Silver: '/static/images/silver.jpg',
  Fire: '/static/images/fire.jpg',
  Gem: '/static/images/gem.jpg'
};



// 在文本加载完成后调用


function loadTexture(config) {
  try {
    if (!config) return null;

    // 支持直接传路径字符串
    if (typeof config === 'string') {
      config = { url: config };
    }

    const loader = new TextureLoader();
    let textureUrl = '';

    if (config.url) {
      textureUrl = config.url;
    } else if (config.type === 'builtin' && config.id) {
      textureUrl = builtinTextures[config.id] || '';
    }
    if (!textureUrl) {
      console.warn('Missing texture URL:', config);
      return null;
    }

    // 带错误处理的异步加载
    const texture = loader.load(
      textureUrl,
      undefined,
      undefined,
      (error) => console.error('Texture load failed:', error)
    );

    // 自动配置纹理参数
    texture.wrapS = RepeatWrapping;
    texture.wrapT = RepeatWrapping;

    // 高级重复配置系统
    const repeatConfig = config.repeat || (config.scale ? { x: config.scale, y: config.scale } : { x: 1, y: 1 });
    texture.repeat.set(repeatConfig.x, repeatConfig.y);


    // 扩展参数支持
    if (config.flipY !== undefined) texture.flipY = config.flipY;
    if (config.encoding) texture.encoding = config.encoding;

    return texture;
  } catch (error) {
    console.error('Texture loading error:', error);
    return null;
  }
}

// material-factory.js

/* 


*/
function getMaterial(mtlType, config = {}) {
  // 公共参数处理系统
  const parseColor = (value) => value instanceof Color ? value : new Color(value || '#FFFFFF');

  const baseParams = {
    color: parseColor(config.color),
    opacity: Math.min(Math.max(config.opacity ?? 1, 0), 1),
    transparent: config.transparent ?? (config.opacity < 1),
    map: loadTexture(config.map),
    alphaMap: loadTexture(config.alphaMap),
    emissive: parseColor(config.emissive),
    emissiveIntensity: config.emissiveIntensity ?? 0
  };

  // 材质参数验证系统
  const validateParams = (allowedKeys, params) => {
    return Object.keys(params).reduce((acc, key) => {
      if (allowedKeys.includes(key)) acc[key] = params[key];
      else console.warn(`Invalid parameter '${key}' for ${mtlType}`);
      return acc;
    }, {});
  };

  try {
    switch (mtlType) {
      case "MeshPhysicalMaterial":
        return new MeshPhysicalMaterial(validateParams([
          'color', 'metalness', 'roughness', 'map', 'transparent', 'opacity',
          'clearcoat', 'transmission', 'alphaMap', 'emissive', 'emissiveIntensity'
        ], {
          ...baseParams,
          metalness: config.metalness ?? 0.5,
          roughness: config.roughness ?? 0.5,
          clearcoat: config.clearcoat ?? 0,
          transmission: config.transmission ?? 0
        }));

      case "MeshToonMaterial":
         
        return new MeshToonMaterial(validateParams([
          'color', 'gradientMap', 'opacity', 'transparent'
        ], {
          ...baseParams,
          gradientMap: loadTexture(config.gradientMap)
        }));

      case "MeshPhongMaterial":
        return new MeshPhongMaterial(validateParams([
          'color', 'specular', 'shininess', 'map', 'alphaMap'
        ], {
          ...baseParams,
          specular: parseColor(config.specular ?? '#111111'),
          shininess: config.shininess ?? 30
        }));

      case "MeshLambertMaterial":
        return new MeshLambertMaterial(validateParams([
          'color', 'emissive', 'emissiveIntensity', 'map', 'alphaMap'
        ], baseParams));

      case "MeshStandardMaterial":
        return new MeshStandardMaterial(validateParams([
          'color', 'metalness', 'roughness', 'map', 'alphaMap'
        ], {
          ...baseParams,
          metalness: config.metalness ?? 0.5,
          roughness: config.roughness ?? 0.5
        }));

      case "MeshBasicMaterial":
        return new MeshBasicMaterial(validateParams([
          'color', 'map', 'alphaMap', 'transparent', 'opacity', 'wireframe'
        ], {
          ...baseParams,
          wireframe: config.wireframe ?? false
        }));

      case "MeshMatcapMaterial":
        return new MeshMatcapMaterial(validateParams([
          'matcap', 'color', 'alphaMap'
        ], {
          matcap: loadTexture(config.matcap),
          color: baseParams.color,
          alphaMap: baseParams.alphaMap
        }));

      default:
        console.warn(`Unknown material type: ${mtlType}, using StandardMaterial`);
        return new MeshStandardMaterial(baseParams);
    }
  } catch (e) {
    console.error(`Material creation failed for ${mtlType}:`, e);
    return new MeshStandardMaterial(baseParams);
  }
}
class MaterialSystem extends CameraSystem {
  constructor(options = {}) {
    super(options);
  }

  createMaterials(config) {
    const value = [
    ]
    if (config.materials) {
      const materials = config.materials;
      for (var elm of materials) {
        value.push(getMaterial(elm.type, elm))
      }
    } else {
      if (config.mtlType) {
        value.push(getMaterial(config.mtlType, { color: config.mtlColor, textureMap: config.textureMap }))
      }
      if (config.meshToon) {
        value.push(getMaterial('MeshToonMaterial', config.meshToon))
      }
      if (config.meshPhysical) {
        value.push(getMaterial('MeshPhysicalMaterial', config.meshPhysical))
      }
      if (config.meshPhong) {
        value.push(getMaterial('MeshPhongMaterial', config.meshPhong))
      }
      if (config.meshStandard) {
        value.push(getMaterial('MeshStandardMaterial', config.meshStandard))
      }



    }
    return value;
  }
}


export default MaterialSystem;